<?php
class db{
	protected $con;
	protected $sql;
	protected $where;
	protected $sqlQuery;
	private $database;
	public function __construct(){
		$this->initSql();
		$this->connectDb();
	}
	public function connectDb(){
		$this->database=database::getInstance();
		$this->con =$this->database->_db;
	}
	public function closeDb(){
		if (is_resource($this->con)){
			mysql_close($this->con);
		}
		$this->con='';
	}
	public function query($sql=''){
		$query='';
		$sqlCentense='';
		if($sql){
			$sqlCentense=$sql;
			$this->sqlQuery=$sql;
		}else if(is_array($this->sql)&&!empty($this->sql)){
			$sqlCentense = $this->prepareSql();
		}
		if($sqlCentense){		
			if(!is_resource($this->con)){
				$this->connectDb();
			}
			$query = mysql_query($sqlCentense,$this->con);
		}
		
		$this->initSql();
		return $query;
	}
	public function fetchAll($sql='',$model='MYSQL_ASSOC'){
		$result = $this->query($sql);
		$data=array();
		if($result){
			if($model=='MYSQL_BOTH'){
				while($row=mysql_fetch_array($result,MYSQL_BOTH)){
					$data[]=$row;
				}
			}else if($model=='MYSQL_NUM'){
				while($row=mysql_fetch_array($result,MYSQL_NUM)){
					$data[]=$row;
				}
			}else{
				while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
					$data[]=$row;
				}
			}
		}
		return $data;
	}
	public function fetch($sql='',$model='MYSQL_ASSOC'){
		$result = $this->query($sql);
		$data=array();
		if($result){
			if($model=='MYSQL_BOTH'){
				while($row=mysql_fetch_array($result,MYSQL_BOTH)){
					$data=$row;
					break;
				}
			}else if($model=='MYSQL_NUM'){
				while($row=mysql_fetch_array($result,MYSQL_NUM)){
					$data=$row;
					break;
				}
			}else{
				while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
					$data=$row;
					break;
				}
			}
		}
		return $data;
	}
	public function where($condition){
		if(is_array($condition)){
			foreach($condition as $cond):
				$this->sql['where'][0][]=$cond;
			endforeach;
		}else{
			$this->sql['where'][0][]=$condition;
		}
		return $this;
	}
	public function orwhere($condition){
		if(is_array($condition)){
			foreach($condition as $cond):
				$this->sql['where'][1][]=$cond;
			endforeach;
		}else{
			$this->sql['where'][1][]=$condition;
		}
		return $this;
	}
	public function from($table){
		if($table!==''):
			$this->from[]=$table;
		endif;
	}
	public function insert($table,$colums,$values){
		$this->prepareQuery($table,$colums,$values,'insert into');
		return $this;
	}
	
	public function update($table,$colums,$values){
		$this->prepareQuery($table,$colums,$values,'update');
		return $this;
	}
	public function delete($table,$condition){
		$this->prepareQuery($table,'','','delete');
		$this->where($condition);
		return $this;
	}
	public function join($table,$condition,$colums){
		$this->setJoin($table,$condition,$colums,"inner join");
		return $this;
	}
	public function leftJoin($table,$condition,$colums){
		$this->setJoin($table,$condition,$colums,"left join");
		return $this;
	}
	public function rightJoin($table,$condition,$colums){
		$this->setJoin($table,$condition,$colums,"right join");
		return $this;
	}
	public function fullJoin($table,$condition,$colums){
		$this->setJoin($table,$condition,$colums,"full join");
		return $this;
	}
	public function setJoin($table,$condition,$colums,$type){
		$columArray=array();
		if(is_array($colums)){
			$columArray=$colums;
		}else {
			$columArray[] =$colums;
		}
		foreach($columArray as $colum){
			$this->sql['colum'][] = $table.".".$colum;
		}
		$this->sql['join'].=" ".$type." ".$table." ON ".$condition;
		return $this;
	}
	public function order($colums,$derection='ASC'){
		$columsArray =array();
		$derectionArray = array();
		if(is_array($colums)&&$colums){
			$columsArray=$colums;
		}else{
			$columsArray[]=$colums;
		}
		if(is_array($derectionArray)&&$derectionArray){
			$derectionArray=$derection;
		}else{
			$derectionArray[]=$derection;
		}
		$orderBy='';
		foreach($columsArray as $key=>$colum){
			$dir = isset($derectionArray[$key])&&($derectionArray[$key])?($derectionArray[$key]):'ASC';
			if($orderBy){
				$orderBy .=",".$colum." ".$dir;
			}else{
				$orderBy =$colum." ".$dir;
			}
		}
		if($this->sql['order']){
			$this->sql['order'].=",".$orderBy;
		}else{
			$this->sql['order']=$orderBy;
		}
		return $this;
	}
	public function limit($number,$offset=0){
		$limit = ' limit '.$offset.",".$number;
		$this->sql['limit']=$limit;
		return $this;
	}
	public function select($table,$colums='*'){
		$this->prepareQuery($table,$colums,'','select');
		return $this;
	}
	public function group($colum){
		if($this->sql['group']){
			$this->sql['group'].=" ,".$colum;
		}else{
			$this->sql['group'].=$colum;
		}
		return $this;
	}
	public function having($expression){
		if($this->sql['having']){
			$this->sql['having'].=" ,".$expression;
		}else{
			$this->sql['having'].=$expression;
		}
	}
	public function initSql(){
		$this->sql=array();
		$this->sql['join']='';
		$this->sql['where']=array();
		$this->sql['colum']=array();
		$this->sql['order']='';
		$this->sql['limit']='';
		$this->sql['group']='';
		$this->sql['having']='';
		$this->sql['table']=array();
		$this->sql['command']=array();
	}
	public function getSql(){
		return $this->prepareSql();
	}
	protected function prepareQuery($table,$colums,$values,$command){
		$columsArray=array();
		$valuesArray=array();
		if(!is_array($colums)){
			$columsArray[]=$colums;
		}else{
			$columsArray=$colums;
		}
		if(!is_array($values)){
			$valuesArray[]=$values;
		}else{
			$valuesArray=$values;
		}
		if((count($columsArray)==count($valuesArray))||$command=='select'){
			foreach($columsArray as $colum){
				if ($colum instanceof expression){
					$this->sql['colum'][]=$colum->getString();
					continue;
				}
				$this->sql['colum'][]=$table.".".$colum;
			}
			foreach($valuesArray as $value){
				$this->sql['values'][]=$value;
			}
			$this->sql['table'][]=$table;
			$this->sql['command'][]=$command;
		}
	}
	
	protected function prepareSql(){
		$sql = $this->sql;
		$command =$sql['command'][0];
		$centense = '';
		$where = isset($sql['where'])?$sql['where']:'';
		$order = isset($sql['order'])?$sql['order']:'';
		$limit = isset($sql['limit'])?$sql['limit']:'';
		$join = isset($sql['join'])?$sql['join']:'';
		$group = isset($sql['group'])?$sql['group']:'';
		$having = isset($sql['having'])?$sql['having']:'';
		if($command=='insert into'){		
			$centense=$command." ".($sql['table'][0])." ";
			$colums='';
			if($sql['colum']&&is_array($sql['colum'])){
				foreach($sql['colum'] as $colum){
					if($colums){
						$colums.=",".$colum;
					}else{
						$colums=$colum;
					}	
				};
			}
			$centense.="(".$colums.")"." ";
			$values='';
			if($sql['values']&&is_array($sql['values'])){
				foreach($sql['values'] as $value):
					if($values){
						$values.=",'".$value."'";
					}else{
						$values="'".$value."'";
					}
				endforeach;
			}
			$centense.="values (".$values.")";
		}
		else if($command=='update'){
			$centense=$command." ".($sql['table'][0])." ";
			$newValues='';
			if($sql['colum']&&is_array($sql['colum'])){
				foreach($sql['colum'] as $key=>$colum ){
					if($newValues){
						$newValues.=",".$colum."='".($sql['values'][$key])."'";						
					}else{
						$newValues=$colum."='".($sql['values'][$key])."'";
					}
				}
			}
			$centense.="set ".$newValues;
		}
		else if($command=='delete'){
			$centense=$command." from ".($sql['table'][0])." ";
		}
		else if($command=='select'){
			$colums='';
			if($sql['colum']&&is_array($sql['colum'])){
				foreach($sql['colum'] as $colum){
					if($colums){
						$colums.=",".$colum;
					}else{
						$colums=$colum;
					}	
				};
			}else {
				$colums='*';
			}
			$centense=$command." ".$colums." from ".($sql['table'][0]);
		}
		if($join){
			$centense.=$join;
		}
		if(!empty($where)&&$centense){
			$conditions='';
			if(!empty($where[0])){
				foreach($where[0] as $condition){
					if($conditions){
						$conditions.=" and ".$condition;
					}else{
						$conditions="(".$condition;
					}	
				}
				if($conditions){
					$conditions.=")";
				}
			}
			$orCondition='';
			if(!empty($where[1])){
				foreach($where[1] as $condition){
					if($orCondition){
						$orCondition.=" or ".$condition;
					}else{
						$orCondition="(".$condition;
					}	
				}
				if($orCondition){
					$orCondition.=")";
				}	
			}
			$mergeWhere ='';
			if($conditions){
				$mergeWhere=$conditions;
			}
			if($mergeWhere&&$orCondition){
				$mergeWhere.=" or ".$orCondition;
			}
			if(!$mergeWhere&&$orCondition){
				$mergeWhere=$orCondition;
			}
			if($mergeWhere&&$centense){
				$centense.=" where ".$mergeWhere;
			}
		}
		if($group){
			$centense.=" group by ".$group;
		}
		if($having){
			$centense .=" having ".$having;
		}
		if($order){
			$centense.=" order by ".$order;
		}
		if($limit){
			$centense.=$limit;
		}
		$this->sqlQuery=$centense;
		return $centense;
	}
	private function __set($vara,$value){
		$this->$vara=$value;

	}
	private function __get($vara){
		if(isset($this->$vara)){
			return $this->$vara;
		}else{
			return null;
		}
	}
	public function __destruct(){
		// $this->closeDb();
	}
}
?>